﻿using System.Collections.Generic;
using System.IO;
using Common;
using Moq;
using PluginFramework.Packages;
using PluginFramework.Plugins;
using Xunit;
using System;
using System.Diagnostics;
using System.Linq;

namespace PluginTests.PluginsTests
{
	public class PluginManagerTests:IDisposable
	{
		private Stopwatch _t = new Stopwatch();
		private PluginsStateManager _plug;
		private PackageManager _pm;
		private Mock<IPluginRepository> _repo;

		public PluginManagerTests()
		{
			Setup.SetPackageManagerPath();
			_pm = new PackageManager(Setup.SettingsProvider().Object);
			try
			{
				_pm.CopyToCache();
			}
			catch
			{
				//needed for testing
				Console.WriteLine("Ignored CopyToCache");
			}
			_pm.LoadPackages();
			_repo = Setup.PLuginRepository();
			_plug = _pm.CreatePluginsManager(_repo.Object);			
		}

		[Fact]
		public void get_availabe_plugins_returns_plugin_status()
		{
			_repo.Setup(d => d.GetActivePlugins()).Returns(new List<string>() {"MyPlugin"});
			var plugs = _plug.GetAvailablePlugins();
			Assert.True(plugs.First(d=>d.PluginInfo.Id=="MyPlugin").IsActive);
			Assert.False(plugs.First(d=>d.PluginInfo.Id=="MyWidgetId").IsActive);			
		}

		[Fact]
		public void removed_packages_plugins_dont_show_anywhere()
		{
			Assert.Equal(2,_plug.GetAvailablePlugins().Count());
			_pm.RemovePackageFromConfig("Plugin2");
			var all = _plug.GetAvailablePlugins();
			Assert.Equal(1,all.Count());
			Assert.Equal("Widgets",all.First().PluginInfo.Package);
			Assert.Null(_plug.CreateInstance<IPlugin>("MyPlugin"));
		}

		[Fact]
		public void instance_creation()
		{
			var p = _plug.CreateInstance<IPlugin>("MyPlugin");
			Assert.NotNull(p);
		}

		[Fact]
		public void plugin_not_found_returns_null()
		{
			Assert.Null(_plug.CreateInstance<IPlugin>("Test"));
		}
		private void Write(string format, params object[] param)
		{
			Console.WriteLine(format, param);
		}

		[Fact]
		public void save_plugin_state_works_ok()
		{
			var plug = new List<PluginStateUpdater>();
			plug.Add(new PluginStateUpdater(){Id = "MyWidgetId",IsActive = true});
			_plug.UpdateState(plug);
			var rez = new List<string>() {"MyWidgetId"};
			_repo.Verify(d=>d.UpdatePluginsState(rez));
		}

		[Fact]
		public void save_null_or_empty_list_does_nothing()
		{
			_plug.UpdateState(null);
			_repo.Verify(d=>d.UpdatePluginsState(It.IsAny<IEnumerable<string>>()),Times.Never());
		}

		[Fact]
		public void save_only_active_items()
		{
			_repo.Setup(d => d.GetActivePlugins()).Returns(new[] {"MyPlugin", "MyWidgetId"});
			var saveData = new List<PluginStateUpdater>();
			saveData.Add(new PluginStateUpdater(){Id="MyPlugin"});
			saveData.Add(new PluginStateUpdater(){Id="MyWidgetId"});
			_plug.UpdateState(saveData);
			
			_repo.Verify(d=>d.UpdatePluginsState(new string[0]),Times.Once());
		}

		public void Dispose()
		{
			_pm.Dispose();			
		}
	}
}